home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / comm / bbs / BBBBS84.lha / rexx / bbsMsg.rexx < prev    next >
Encoding:
OS/2 REXX Batch file  |  1994-12-23  |  35.4 KB  |  1,469 lines

  1. /* $VER: bbsMsg.rexx 8.3 (23.12.94)
  2. copyright © 1990-1994 Richard Lee Stockton
  3. BBBBS offline message conference handler
  4. FREELY DISTRIBUTABLE
  5. */
  6.  
  7. IF ~SHOW('P','QuickSortPort') THEN CALL setup.rexx()
  8. IF ~SHOW('P','QuickSortPort') THEN EXIT 666
  9.  
  10. OPTIONS RESULTS
  11. SIGNAL ON BREAK_C
  12. SIGNAL ON BREAK_E
  13. SIGNAL ON FAILURE
  14. SIGNAL ON SYNTAX
  15.  
  16. CALL TIME('R')
  17.  
  18. PARSE ARG maxtime name pw 
  19. If ~DATATYPE(maxtime,'N') THEN maxtime=6000
  20.  
  21. title.=''
  22. title.1='BBBBS Message Handler'
  23. title.2='Version 8.3'
  24. title.3='8-Dec-94'
  25.  
  26. IF ADDRESS()='BAUD' THEN
  27.   DO
  28.     CR='0D'x
  29.     frombb=1
  30.   END
  31. ELSE
  32.   DO
  33.     CR=''
  34.     frombb=0
  35.   END
  36.  
  37. CALL config()
  38. clear_marked=0
  39. namemask=COMPRESS(XRANGE(),XRANGE('A','Z')' _-')
  40. IF name='' THEN
  41.   DO
  42.     OPTIONS PROMPT ' Are you 'sysop'? (Yn) > '
  43.     PULL answer
  44.     IF answer='N' THEN
  45.       DO
  46.         SAY
  47.         OPTIONS PROMPT ' Please enter your name > '
  48.         PULL name
  49.         name=cleanstring('1:'name)
  50.         IF name='' THEN EXIT 
  51.       END
  52.     ELSE name=sysop
  53.   END
  54. IF ~EXISTS(bbspath'Users/'name) THEN
  55.   DO
  56.     SAY name 'does not exist!'
  57.     EXIT
  58.   END
  59. CALL loaddata()
  60. IF pw~=password THEN
  61.   DO
  62.     passprompt=pen3' Please Enter Password: '
  63.     DO tries=1 TO 3
  64.       OPTIONS PROMPT passprompt
  65.       PULL newpassword
  66.       SAY def
  67.       IF(password=newpassword) THEN LEAVE tries; /* correct password */
  68.       IF tries=3 THEN
  69.         DO
  70.           SAY 
  71.           SAY 'Access terminated.'
  72.           SAY '*** Bad password ***' newpassword '***'
  73.           EXIT
  74.         END
  75.       passprompt='Incorrect.  Password: ' /* ask again */
  76.     END
  77.     SAY
  78.     SAY' OK, 'name' here we go....'
  79.     SAY
  80.   END
  81. msg.=''
  82. IF readopen(bbspath'Lists/Conferences') THEN
  83.   DO
  84.     DO i=1
  85.       line=READLN(f)
  86.       IF line='END' THEN BREAK
  87.       IF EOF(f) THEN BREAK
  88.       num=WORD(line,1)
  89.       IF DATATYPE(num,'W') THEN msg.num=WORD(line,2)
  90.     END
  91.     CALL CLOSE(f)
  92.   END
  93. SAY '                        'lineup||CR
  94. searcharg=GETCLIP('BBSMSG_SEARCH')
  95. IF searcharg~='' THEN
  96.   DO
  97.     CALL SETCLIP('BBSMSG_SEARCH')
  98.     CALL search()
  99.     EXIT
  100.   END
  101. IF ARG()=0 THEN
  102.   DO
  103.     DO i=1 TO 3
  104.       SAY CENTER(title.i,75)
  105.     END
  106.     SAY CR
  107.   END
  108. CALL sortconferences()
  109. CALL readmessages()
  110. EXIT
  111.  
  112.  
  113. /* sub-routines */
  114.  
  115. config:
  116. arg='s:CONFIG.BBS'
  117. IF ~EXISTS(arg) THEN arg='BBS:BBS_TEXT/CONFIG.BBS'
  118. IF readlines(arg 1) THEN
  119.   DO
  120.     SAY 's:CONFIG.BBS and BBS:BBS_TEXT/CONFIG.BBS are both missing!'CR
  121.     EXIT
  122.   END
  123. compos=POS('/*',lynes.1)
  124. IF compos>0 THEN lynes.1=LEFT(lynes.1,compos-1)
  125. bbsname=STRIP(lynes.1)
  126. sysop=WORD(lynes.2,1)
  127. compos=POS('/*',lynes.3)
  128. IF compos>0 THEN lynes.3=LEFT(lynes.3,compos-1)
  129. exclusion=STRIP(lynes.3)
  130. bbsdevice=WORD(lynes.4,1)
  131. sysoplevel=WORD(lynes.5,1)
  132. bbspath=WORD(lynes.6,1)
  133. IF ~EXISTS(bbspath) THEN
  134.   DO
  135.     SAY bbspath 'does not exist!'CR
  136.     EXIT
  137.   END
  138. testchar=RIGHT(bbspath,1)
  139. IF testchar~='/' & testchar~=':' THEN bbspath=bbspath'/'
  140. msgpath=WORD(lynes.7,1)
  141. IF ~EXISTS(msgpath) THEN
  142.   DO
  143.     SAY msgpath 'does not exist!'CR
  144.     EXIT
  145.   END
  146. testchar=RIGHT(msgpath,1)
  147. IF testchar~='/' & testchar~=':' THEN msgpath=msgpath'/'
  148. msgpath=msgpath'MSG'
  149. DO i=16 TO 41
  150.   j=i-15
  151.   bbsprefs.j=STRIP(WORD(lynes.i,1))
  152. END
  153. IF bbsprefs.10 THEN scratch=bbspath'Scratch'
  154. ELSE scratch='RAM:Scratch'
  155. CALL MAKEDIR(scratch)
  156. IF ~DATATYPE(bbsprefs.16,'W') THEN bbsprefs.16=3
  157. RETURN
  158.  
  159.  
  160. sortconferences:
  161. count=0
  162. smsg.=''
  163. DO i=1 TO level
  164.   IF msg.i='' THEN ITERATE i
  165.   count=count+1
  166.   smsg.count=msg.i i
  167. END
  168. smsg.0=count
  169. IF count>0 THEN CALL QSort(1,count,smsg)
  170. count=0
  171. msgs.=''
  172. DO i=1 TO smsg.0
  173.   tempnum=WORD(smsg.i,2)
  174.   tempdir=WORD(smsg.i,1)
  175.   IF FIND(data.21,tempnum)=0 THEN
  176.     DO
  177.       string=' '
  178.       IF tempnum<10 THEN string=string' '
  179.       string=string || tempnum'.'
  180.       IF WORD(data.22,tempnum)='' | WORD(data.22,tempnum)>=0 THEN
  181.         string=string LEFT(tempdir,20)
  182.       ELSE string=string pen3'-OFF-'def LEFT(tempdir,14)
  183.       count=count+1
  184.       msgs.count=string
  185.     END
  186. END
  187. msgs.0=count%3
  188. IF (count//3)>0 THEN msgs.0=msgs.0+1
  189. DO i=1 TO msgs.0
  190.   DO j=1 TO 2
  191.     k=i+j*msgs.0
  192.     IF k<=count THEN msgs.i=msgs.i msgs.k
  193.   END
  194. END
  195. RETURN
  196.  
  197.  
  198. areaselect:
  199. SAY pen3||LEFT('-',75,'-')||def||CR
  200. DO i=1 TO msgs.0
  201.   SAY msgs.i||CR
  202.   IF i//linesperpage=0 & i<msgs.0 THEN CALL waiting()
  203. END
  204. SAY pen3||LEFT('-',75,'-')||def||CR
  205. temp=getinput(1 0 pen3'Select Message Conference: 'def)
  206. IF ~DATATYPE(temp,'W') | temp<1 | temp>level | FIND(data.21,temp)>0 THEN RETURN 1
  207. IF msg.temp='' THEN RETURN 1
  208. msgdir=temp
  209. RETURN 0
  210.  
  211.  
  212. showmarked:
  213. IF WORDS(data.24)<1 THEN RETURN
  214. fline='These unread conference messages have been ['pen3'M'pen6']arked as addressed to you:'
  215. SAY CR
  216. SAY pen6||fline||def||CR
  217. tempkk=data.24
  218. DO i=1 TO WORDS(tempkk)
  219.   tempk=WORD(tempkk,i)
  220.   PARSE VAR tempk kdir'/'kmsg
  221.   line=RIGHT(kmsg,6) 'in the'pen3 msg.kdir def'conference'
  222.   IF EXISTS(msgpath||tempk) THEN SAY line'.'CR
  223.   ELSE
  224.     DO
  225.       SAY line 'is missing.'CR
  226.       mkw=FIND(data.24,tempk)
  227.       data.24=STRIP(DELWORD(data.24,mkw,1))
  228.       CALL savedata(0)
  229.     END
  230. END
  231. SAY CR
  232. RETURN
  233.  
  234.  
  235. readmessages:
  236. x=GETCLIP('BBSMSG_ARG')
  237. IF x~='' THEN
  238.   DO
  239.     CALL SETCLIP('BBSMSG_ARG')
  240.     colorflag=WORD(x,1)
  241.     IF WORDS(x)>1 THEN arg=SUBSTR(x,WORDINDEX(x,2))
  242.     ELSE arg=''
  243.   END
  244. searcharg=''
  245. DO FOREVER
  246.   SAY CR
  247.   PARSE VAR arg temp' 'arg .
  248.   IF DATATYPE(temp,'W') THEN msgdir=temp
  249.   ELSE IF LEFT(UPPER(temp),1)='A' THEN
  250.     DO
  251.       CALL newmsgs()
  252.       arg=''
  253.       RETURN
  254.     END
  255.   ELSE IF LEFT(UPPER(temp),1)='M' THEN
  256.     DO
  257.       CALL readmarked()
  258.       arg=''
  259.       RETURN
  260.     END
  261.   ELSE
  262.     DO
  263.       CALL showmarked()
  264.       SAY 'Select Message Conference By' pen3'Number'def', ['pen3'M'def']arked only or ['pen3'A'def']ll Active'CR
  265.       IF areaselect() THEN
  266.         DO
  267.           IF LEFT(temp,1)='A' THEN CALL newmsgs()
  268.           IF LEFT(temp,1)='M' THEN CALL readmarked()
  269.           RETURN
  270.         END
  271.     END
  272.   pline='['pen3'A'def']rchive ['pen3'S'def']earch ['pen3'T'def']oggle ON/OFF'
  273.   pline=pline '['pen3'P'def']ost ['pen3'R'def']ead ['pen3'Q'def']uit (apqRst) > '
  274.   IF WORD(data.22,msgdir)<0 THEN
  275.     pline='['pen3'T'def']oggle ON/OFF ['pen3'Q'def']uit (qT) > '
  276.   IF arg~='' THEN junk=UPPER(LEFT(arg,1))
  277.   ELSE junk=getinput(1 1 pline)
  278.   IF WORD(data.22,msgdir)<0 & junk~='Q' THEN junk='T'
  279.   IF junk='Q' THEN RETURN
  280.   IF junk='P' THEN
  281.     DO
  282.       CALL bbsWrite.rexx(name maxtime-TRUNC(TIME('E')) 'MSG' . . 0 msgdir)
  283.       RETURN
  284.     END
  285.   IF junk='A' THEN
  286.     DO
  287.       SAY CR
  288.       CALL msgcount(msgdir)
  289.       junk=getinput(1 0 pen3'RETURN'def' to archive new msgs, ['pen3'Q'def']uit, or enter starting message number > ')
  290.       IF junk='Q' THEN RETURN
  291.       IF DATATYPE(junk,'W') THEN
  292.         DO
  293.           IF junk>lastmess | junk<1 THEN junk=1
  294.           lastread.msgdir=junk-1
  295.           CALL savedata(1)
  296.         END
  297.       CALL SETCLIP('BBS_MSGS','ON')
  298.       SAY 'Archiving messages in the'pen3 msg.msgdir def'Conference...'CR
  299.       lastread.msgdir=countcheck(bbspath'Numbers/LastMessage'msgdir 0)
  300.       CALL send2log('Arc: ArcMsgs.rexx' msg.msgdir)
  301.       ADDRESS AREXX ArcMsgs.rexx name msgdir
  302.       DO WHILE GETCLIP('BBS_MSGS')~=''
  303.         CALL DELAY(14)
  304.       END
  305.       SAY 'When completed, the archive will be attached to email addressed to you.'CR
  306.       CALL savedata(1)
  307.       SAY CR
  308.       RETURN
  309.     END
  310.   IF junk='S' THEN
  311.     DO
  312.       searcharg=''
  313.       searcharg=getinput(0 0 pen3'Search Phrase: 'def)
  314.       IF LENGTH(STRIP(searcharg))=0 THEN RETURN
  315.       searcharg=COMPRESS(searcharg,'*')
  316.       SAY CR
  317.       CALL searchmsgdir()
  318.       SAY CR
  319.       SAY lineup'All messages in the'pen3 msg.msgdir def'Conference have been searched.'CR
  320.       SAY CR
  321.       CALL waiting()
  322.       searcharg=''
  323.       RETURN
  324.     END
  325.   IF junk='T' THEN
  326.     DO
  327.       line='Turning the' msg.msgdir 'conference'
  328.       IF WORD(data.22,msgdir)<0 THEN
  329.         DO
  330.           line=line pen3'ON'def'.'
  331.           newdata='0'
  332.         END
  333.       ELSE
  334.         DO
  335.           line=line pen3'OFF'def'.'
  336.           newdata='-1'
  337.         END
  338.       SAY line||CR
  339.       dataloc=WORDINDEX(data.22,msgdir)-1
  340.       data.22=DELWORD(data.22,msgdir,1)
  341.       IF dataloc>0 THEN data.22=INSERT(newdata' ',data.22,dataloc)
  342.       CALL sortconferences()
  343.     END
  344.   CALL readmsg(0)
  345.   CALL savedata(1)
  346.   nonstop=0
  347.   arg=''
  348. END
  349. RETURN
  350.  
  351.  
  352. newmsgs:
  353. test=UPPER(LEFT(arg,1))
  354. IF test='' THEN
  355.   test=getinput(1 1 '['pen3'R'def']ead new messages or ['pen3'A'def']rchive for later download. (aR) > ')
  356. IF test='A' THEN
  357.   DO
  358.     CALL SETCLIP('BBS_MSGS','ON')
  359.     SAY CR
  360.     SAY 'Archiving new conference messages...'CR
  361.     CALL send2log('Arc: ArcMsgs.rexx')
  362.     ADDRESS AREXX ArcMsgs.rexx name
  363.     clear_marked=1
  364.     DO i=1 TO level
  365.       IF WORD(data.22,i)~=-1 THEN
  366.         lastread.i=countcheck(bbspath'Numbers/LastMessage'i 0)
  367.     END
  368.     DO WHILE GETCLIP('BBS_MSGS')~=''
  369.       CALL DELAY(14)
  370.     END
  371.     SAY 'When completed, the archive will be attached to email addressed to you.'CR
  372.     CALL savedata(1)
  373.     SAY CR
  374.     RETURN
  375.   END
  376. curmsgdir=msgdir
  377. SAY 'Scanning all Conferences for new messages..'CR
  378. DO newi=1 TO level
  379.   IF msg.newi='' THEN ITERATE newi
  380.   msgdir=newi
  381.   CALL readmsg(1)
  382.   IF msgcom='Q' THEN LEAVE newi
  383. END
  384. CALL savedata(1)
  385. msgdir=curmsgdir
  386. nonstop=0
  387. RETURN
  388.  
  389.  
  390. search:
  391. IF searcharg='' THEN searcharg=getinput(0 0 pen3'Search Phrase: 'def)
  392. IF LENGTH(STRIP(searcharg))=0 THEN RETURN
  393. searcharg=COMPRESS(searcharg,'*')
  394. IF getinput(1 1 'Search one conference only? (Ny) > ')='Y' THEN
  395.   DO
  396.     IF areaselect() THEN RETURN
  397.     SAY 'Searching' msg.msgdir 'Message Conference for'pen3 searcharg||def'...'
  398.     SAY
  399.     CALL searchmsgdir()
  400.   END
  401. ELSE
  402.   DO
  403.     SAY 'Searching All Public Message Conferences for'pen3 searcharg||def'...'
  404.     SAY
  405.     DO i=1 TO level
  406.       msgdir=i
  407.       IF msg.msgdir='' | FIND(data.21,msgdir)>0 THEN ITERATE i
  408.       CALL searchmsgdir()
  409.       i=msgdir
  410.       IF msgcom='Q' THEN i=999999
  411.     END
  412.   END
  413. searcharg=''
  414. nonstop=0
  415. SAY CR
  416. IF i<999999 THEN SAY lineup'All available items have been searched.                        'CR
  417. SAY CR
  418. CALL waiting()
  419. RETURN
  420.  
  421.  
  422. searchmsgdir:
  423. msglist=SHOWDIR(msgpath||msgdir)
  424. IF WORDS(msglist)>0 THEN SAY lineup||RIGHT(msg.msgdir,40)||CR
  425. CALL postuser('SEARCH:' msg.msgdir 'for' searcharg)
  426. qi=WORDS(msglist)
  427. msglist=sortnumbers(msglist)
  428. DO wi=1 TO qi
  429.   CALL busywait(8 wi qi)
  430.   messnum=WORD(msglist,wi)%1
  431.   IF textsearch(msgpath||msgdir'/'messnum searcharg) THEN
  432.     DO
  433.       CALL busywait(4 0)
  434.       savelast=lastread.msgdir
  435.       CALL readmsg(0 messnum)
  436.       lastread.msgdir=savelast
  437.       IF msgcom='Q' THEN RETURN
  438.       CALL busywait(4 1)
  439.     END
  440. END
  441. CALL busywait(4 0)
  442. RETURN
  443.  
  444.  
  445. textsearch:
  446. ARG sfile' 'sarg
  447. IF sarg='' THEN RETURN 0
  448. x=OPEN(f,sfile,'R')
  449. IF x=0 THEN RETURN 0
  450. stemp=UPPER(READCH(f,65000))
  451. CALL CLOSE(f)
  452. retflag=0
  453. IF POS(sarg,stemp)>0 THEN retflag=1
  454. RETURN retflag
  455.  
  456.  
  457. sortnumbers:
  458. PARSE ARG slist
  459. IF STRIP(slist)='' THEN RETURN ''
  460. sorted.=''
  461. oldest=999999
  462. newest=0
  463. newlist=''
  464. DO si=1 TO WORDS(slist)
  465.   testword=WORD(slist,si)
  466.   IF ~DATATYPE(testword,'W') THEN
  467.     DO
  468.       testpos=LASTPOS('.',testword)
  469.       IF testpos>0 THEN tempnum=SUBSTR(testword,testpos+1)
  470.       ELSE
  471.         DO
  472.           newlist=testword newlist
  473.           ITERATE si
  474.         END
  475.     END
  476.   ELSE tempnum=testword/1
  477.   IF sorted.tempnum='' THEN
  478.     DO
  479.       sorted.tempnum=testword
  480.       sorted.tempnum.0=1
  481.       IF DATATYPE(tempnum,'W') THEN
  482.         DO
  483.           IF tempnum>newest THEN newest=tempnum
  484.           IF tempnum<oldest THEN oldest=tempnum
  485.         END
  486.     END
  487.   ELSE newlist=newlist testword
  488. END
  489. IF oldest~=999999 & newest~=0 THEN
  490.   DO si=oldest TO newest
  491.     IF sorted.si.0=1 THEN newlist=newlist sorted.si
  492.   END
  493. DROP sorted. oldest newest
  494. RETURN STRIP(newlist)
  495.  
  496.  
  497. postuser:
  498. IF ~frombb | bbsprefs.12~=1 | ~SHOW('P','BBSPOST') THEN RETURN
  499. PARSE ARG parg 
  500. ptext=GETCLIP('BBSPOST4')
  501. IF WORDS(ptext)>4 THEN ptext=LEFT(ptext,WORDINDEX(ptext,5)-1)
  502. ptext=STRIP(ptext)
  503. ptext=CENTER(ptext'   'parg,74)
  504. CALL SETCLIP('BBSPOST4',ptext)
  505. ADDRESS BBSPOST 'UPDATE'
  506. RETURN
  507.  
  508.  
  509. readmsg:
  510. ARG quietflag marknum .
  511. msgcom=''
  512. IF msg.msgdir='' | FIND(data.21,msgdir)>0 THEN RETURN; /* sysop excluded */
  513. IF WORD(data.22,msgdir)=-1 THEN RETURN;                /*  user excluded */
  514. entering='Entering'pen3 msg.msgdir def'Message Conference..'
  515. IF quietflag=0 & marknum='' THEN SAY entering||CR
  516. IF DATATYPE(WORD(data.22,msgdir),'W') THEN
  517.   lastread.msgdir=WORD(data.22,msgdir)
  518. ELSE lastread.msgdir=0
  519. lstwrt=countcheck(bbspath'Numbers/LastMessage'msgdir 0)
  520. frstwrt=countcheck(bbspath'Numbers/FirstMessage'msgdir 0)
  521. temp=''
  522. IF marknum='' THEN
  523.   DO
  524.     IF lastread.msgdir>=lstwrt | lastread.msgdir<frstwrt THEN
  525.       DO
  526.         CALL msgcount(msgdir)
  527.         IF quietflag=1 & lastread.msgdir=lstwrt THEN RETURN
  528.         IF nonstop=1 THEN temp=lastread.msgdir
  529.         ELSE temp=getinput(1 0 pen3'Enter starting message number > 'def)
  530.         IF temp='' & lastread.msgdir<lstwrt THEN temp=lastread.msgdir
  531.         IF ~DATATYPE(temp,'W') THEN RETURN
  532.         IF temp<frstwrt THEN temp=frstwrt
  533.         IF temp>lstwrt THEN temp=lstwrt
  534.         IF temp<1 THEN temp=1
  535.         lastread.msgdir=temp-1
  536.       END
  537.   END
  538. ELSE lastread.msgdir=marknum-1
  539. CALL postuser('Reading:' msg.msgdir)
  540. IF quietflag=1 THEN SAY entering||CR
  541. t=msgpath||msgdir'.txt'
  542. IF ~terseflag & marknum='' & EXISTS(t) THEN
  543.   DO
  544.     SAY CR
  545.     CALL readlines(t 1)
  546.     saveflag=nonstop
  547.     CALL seelines(1)
  548.     nonstop=saveflag
  549.     SAY CR
  550.   END
  551. dirname=msgpath||msgdir
  552. msglist.=0 /* set read to 0, unread to 1, and reply >=2 */
  553. firstmess=999999
  554. testlist=SHOWDIR(dirname)
  555. DO i=1 TO WORDS(testlist)
  556.   test=WORD(testlist,i)
  557.   IF test>lastread.msgdir THEN msglist.test=1
  558.   IF test<firstmess THEN firstmess=test
  559. END
  560. IF firstmess=999999 THEN firstmess=0
  561. CALL countcheck(bbspath'Numbers/FirstMessage'msgdir firstmess)
  562. msgstatus=1
  563. IF temp='' & marknum='' THEN CALL msgcount(msgdir)
  564. late.=''
  565. late.0=0
  566. skipsubj.=''
  567. skipsubj.0=0
  568. DO msgloop=1
  569.   lastreadnum=lastread.msgdir
  570.   DO WHILE msglist.lastreadnum=0 & lastreadnum<lstwrt
  571.     lastreadnum=lastreadnum+1
  572.   END
  573.   lastread.msgdir=lastreadnum
  574.   IF lastreadnum=lstwrt & msglist.lstwrt=0 THEN LEAVE msgloop
  575.   DO mess=lastread.msgdir TO lstwrt+1
  576.     IF marknum~='' THEN
  577.       DO
  578.         IF mess>marknum THEN LEAVE msgloop
  579.         mess=marknum
  580.       END
  581.     IF msglist.mess~=msgstatus THEN ITERATE mess
  582.     IF msgstatus>1 THEN SAY 'Following the thread, level' msgstatus-1'.'CR
  583.     msglist.mess=0
  584.     arg=dirname'/'mess
  585.     IF ~EXISTS(arg) THEN
  586.       DO
  587.         SAY 'Message number' mess 'is missing.'CR
  588.         ITERATE mess
  589.       END
  590.     IF ~readopen(arg) THEN ITERATE mess
  591.     firstline=READLN(f)
  592.     secondline=READLN(f)
  593.     thirdline=READLN(f)
  594.     forthline=READLN(f)
  595.     CALL CLOSE(f)
  596.     CALL killmark(msgdir mess)
  597.     DO skp=1 TO skipsubj.0
  598.       IF forthline=skipsubj.skp THEN ITERATE mess
  599.     END
  600.     IF WORDS(firstline)>2 THEN /* if replies, change their num to >1 */
  601.       DO
  602.         thread=SUBSTR(firstline,WORDINDEX(firstline,4))
  603.         DO tindx=1 TO WORDS(thread)
  604.           test=WORD(thread,tindx)
  605.           IF msglist.test~=0 THEN msglist.test=msgstatus+1
  606.         END
  607.       END
  608.     ELSE thread=''
  609.     savearg=arg
  610.     msgcom='A'
  611.     DO msgloop2=1 WHILE msgcom='A' | msgcom='O'
  612.       CALL readlines(arg 1)
  613.       IF nonstop=1 THEN rnonstop=1
  614.       ELSE rnonstop=0
  615.       CALL seelines(2)
  616.       IF name=WORD(lynes.3,2) THEN
  617.         DO
  618.           IF WORDS(lynes.3)//2=0 THEN
  619.             DO
  620.               lynes.3=lynes.3'  (Rcvd)'
  621.               CALL savelines(arg)
  622.             END
  623.         END
  624.       msgcom=''
  625.       CALL checktime()
  626.       IF rnonstop THEN
  627.         DO
  628.           SAY CR
  629.           nonstop=1
  630.           msgcom=''
  631.         END
  632.       ELSE
  633.         DO
  634.           pline=''
  635.           IF level<=sysoplevel | WORDS(lynes.3)<4 THEN pline='['pen3'A'def']gain'
  636.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  637.             pline=pline '['pen3'E'def']dit ['pen3'K'def']ill'
  638.           IF level>sysoplevel THEN pline=pline '['pen3'M'def']ove'
  639.           IF WORDS(lynes.3)>3 THEN pline=pline '['pen3'O'def']riginal'
  640.           pline=pline '['pen3'N'def']onStop ['pen3'R'def']eply'
  641.           IF level=99 THEN pline=pline '['pen3'!'def']'
  642.           pline=pline '['pen3'S'def']kip ['pen3'Q'def']uit ['pen3'?'def']'
  643.           msgcom=getinput(1 0 STRIP(pline)' > ')
  644.           CALL cleanline(0)
  645.         END
  646.       IF DATATYPE(msgcom,'W') & EXISTS(dirname'/'msgcom) THEN
  647.         DO
  648.           arg=dirname'/'msgcom
  649.           IF msgcom>lastread.msgdir THEN lastread.msgdir=msgcom
  650.           msgcom='A'
  651.           ITERATE msgloop2
  652.         END
  653.       ELSE msgcom=LEFT(msgcom,1)
  654.       IF msgcom='Q' THEN LEAVE msgloop
  655.       ELSE IF msgcom='!' & level>sysoplevel THEN
  656.         DO
  657.           CALL DELETE(arg)
  658.           newchar=LEFT(lynes.1,1)
  659.           IF newchar~='!' THEN newchar='!!'
  660.           ELSE newchar='  '
  661.           lynes.1=OVERLAY(newchar,lynes.1,1,2)
  662.           CALL savelines(arg)
  663.           ITERATE msgloop2
  664.         END
  665.       ELSE IF msgcom='A' THEN ITERATE msgloop2
  666.       ELSE IF msgcom='M' & level>sysoplevel THEN
  667.         DO
  668.           prevmsgdir=msgdir
  669.           If ~areaselect() THEN
  670.             DO
  671.               CALL MAKEDIR(msgpath||msgdir)
  672.               himsg=countcheck(bbspath'Numbers/LastMessage'msgdir 0)+1
  673.               lynes.1='  Msg:' himsg
  674.               lynes.3='   To:' WORD(lynes.3,2)
  675.               lynes.5=STRIP(DELWORD(lynes.5,8,1)) msg.msgdir
  676.               nlyn=lynes.0+1
  677.               lynes.0=nlyn
  678.               lynes.nlyn=' *** Moved from the' msg.prevmsgdir 'conference ***'
  679.               CALL savelines(msgpath||msgdir'/'himsg)
  680.               CALL countcheck(bbspath'Numbers/LastMessage'msgdir himsg)
  681.               CALL msgmark(WORD(lynes.3,2) msgdir himsg)
  682.               CALL readlines(arg 1)
  683.               CALL DELETE(arg)
  684.               CALL DELAY(28)
  685.               lynes.0=7
  686.               lynes.7='*** Moved to the' msg.msgdir 'conference, message #'himsg' ***'
  687.               CALL savelines(arg)
  688.             END
  689.           msgdir=prevmsgdir
  690.           msgcom='A'
  691.         END
  692.       ELSE IF msgcom='N' THEN
  693.         DO
  694.           nonstop=1
  695.           msgcom=''
  696.         END
  697.       ELSE IF msgcom='H' | msgcom='?' THEN
  698.         DO
  699.           SAY pen3' - HELP with the Read Messages commands -'def||CR
  700.           SAY ' RETURN reads the next message in line.'CR
  701.           SAY ' 34 will read message number 34, if it exists in this conference.'CR
  702.           SAY ' A  reads this message Again (in case it scrolled off screen).'CR
  703.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  704.             DO
  705.           SAY ' E  puts this message into the online Editor.'CR
  706.           SAY ' K  deletes a message you wrote. you cannot Kill others!'CR
  707.             END
  708.           IF level>sysoplevel THEN
  709.           SAY ' M  move this message to a new conference.'CR
  710.           SAY ' N  displays all new messages without pausing. CTRL-E to Exit!'CR
  711.           SAY ' O  if this message is a reply, will read the Original message.'CR
  712.           SAY ' R  enters the message editor to Reply to this message.'CR
  713.           SAY ' S  allows you to Skip threads or conferences.'CR
  714.         IF level=99 THEN
  715.           SAY ' !  toggles the do-not-purge! flag for this message.'CR
  716.           SAY ' Q  returns to the message menu. (Quit)'CR
  717.           SAY CR
  718.           CALL waiting()
  719.           msgcom='A'
  720.           IF waitchar='Q' THEN LEAVE msgloop
  721.         END
  722.       ELSE IF msgcom='E' THEN
  723.         DO
  724.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  725.             DO
  726.               sline=7
  727.               IF level>sysoplevel THEN sline=1
  728.               CALL bbsEd.rexx(sline arg name maxtime)
  729.               msgcom='A'
  730.             END
  731.         END
  732.       ELSE IF msgcom='S' & mess<lstwrt THEN
  733.         DO
  734.           stemp=''
  735.           req='Skip'
  736.           IF WORDS(lynes.1)>2 THEN req=req 'this ['pen3'T'def']hread or'
  737.           ELSE SAY 'There are no replies to this message.'CR
  738.           req=req 'the entire ['pen3'C'def']onference? ('
  739.           IF WORDS(lynes.1)>2 THEN tst='cqt'
  740.           ELSE tst='cq'
  741.           DO WHILE POS(stemp,UPPER(tst))=0
  742.             stemp=getinput(1 1 req||tst') >')
  743.           END
  744.           IF stemp='T' THEN
  745.             DO
  746.               SAY CR
  747.               SAY pen3 forthline||def||CR
  748.               SAY 'Skipping messages associated with this message...'CR
  749.               SAY CR
  750.               DO i=lastread.msgdir TO lstwrt
  751.                 IF msglist.i>1 THEN msglist.i=0
  752.               END
  753.               skipsubj.0=skipsubj.0+1
  754.               sksb=skipsubj.0
  755.               skipsubj.sksb=forthline
  756.             END
  757.           ELSE IF stemp='C' THEN
  758.             DO
  759.               SAY pen3'Skipping to the last message in the'def msg.msgdir pen3'conference.'def||CR
  760.               lastread.msgdir=lstwrt-1
  761.               lw=lstwrt-1
  762.               msglist.lw=0
  763.               msglist.lstwrt=1
  764.               LEAVE mess
  765.             END
  766.         END
  767.       ELSE IF msgcom='K' THEN
  768.         DO
  769.           IF level>sysoplevel | name=WORD(lynes.2,2) THEN
  770.             DO
  771.               IF getinput(1 1 'Really delete' arg'? (Ny) > ')='Y' THEN
  772.                 DO
  773.                   IF DELETE(arg)=1 THEN
  774.                     SAY pen3||arg||def' has been deleted.'CR
  775.                   msg.msgdir.0=msg.msgdir.0-1
  776.                 END
  777.             END
  778.         END
  779.       ELSE IF msgcom='O' THEN   /* go back and read original */
  780.         DO
  781.           IF WORDS(lynes.3)>3 THEN
  782.             DO
  783.               temp=WORD(lynes.3,4)
  784.               arg=dirname'/'temp
  785.             END
  786.           ELSE SAY 'This is the original message.'CR
  787.         END
  788.       ELSE IF msgcom='R' THEN
  789.         DO
  790.           IF thread~='' & marknum='' THEN
  791.             DO
  792.               li='Read the replies to this message before answering? (nY) > '
  793.               IF getinput(1 1 li)~='N' THEN
  794.                 DO
  795.                   n=late.0+1
  796.                   late.0=n
  797.                   late.n=msgstatus
  798.                   late.n.0=arg
  799.                   ITERATE msgloop2
  800.                 END
  801.             END
  802.           CALL do_reply(mess)
  803.         END
  804.       ELSE IF arg~=savearg THEN /* Continue */
  805.         DO
  806.           msgcom='A'
  807.           arg=savearg
  808.         END
  809.     END
  810.     IF thread~='' THEN
  811.       DO
  812.         thread=''
  813.         msgstatus=msgstatus+1
  814.       END
  815.   END
  816.   IF msgstatus>0 THEN
  817.     DO
  818.       IF msgstatus>1 THEN msgstatus=msgstatus-1
  819.       CALL do_late()
  820.       CALL postuser('Reading:' msg.msgdir)
  821.     END
  822. END
  823. msgstatus=0
  824. CALL do_late()
  825. DROP msglist. skipsubj. late.
  826. IF quietflag~=1 THEN nonstop=0
  827. RETURN
  828.  
  829.  
  830. do_late:
  831. DO lt=1 TO late.0
  832.   IF late.lt='' THEN ITERATE lt
  833.   IF msgstatus<=late.lt THEN
  834.     DO
  835.       SAY CR
  836.       SAY bak2' Reviewing message marked for reply...'def||CR
  837.       late.lt=''
  838.       CALL readlines(late.lt.0 1)
  839.       CALL seelines(2)
  840.       ps='Reply to this message? (nY) > '
  841.       IF getinput(1 1 ps)~='N' THEN CALL do_reply(0)
  842.     END
  843. END
  844. RETURN
  845.  
  846.  
  847. docity:
  848. PARSE ARG citi
  849. citi=TRANSLATE(citi,'          ','+-.,*/()<>')
  850. DO i=WORDS(citi) TO 1 BY -1
  851.   IF DATATYPE(WORD(citi,i),'N') THEN citi=STRIP(DELWORD(citi,i,1))
  852.   IF UPPER(WORD(citi,i))='USA' THEN citi=STRIP(DELWORD(citi,i,1))
  853. END
  854. citi=SPACE(citi,1)
  855. RETURN STRIP(citi)
  856.  
  857.  
  858. do_reply:
  859. ARG mes
  860. CALL postuser('Writing:' msg.msgdir)
  861. msgnum=WORD(lynes.1,2)
  862. toname=WORD(lynes.2,2)
  863. orig=dirname'/'msgnum
  864. subj=STRIP(SUBSTR(lynes.4,7))
  865. IF getinput(1 1 'Should this reply be private for'pen3 toname def'only? (yN) > ')='Y' THEN
  866.   DO
  867.     comm=name maxtime-TIME('E') 'MAIL' toname orig 0 0 subj
  868.     CALL bbsWrite.rexx(comm)
  869.     RETURN
  870.   END
  871. comm=name maxtime-TIME('E') 'REPLY' toname orig msgnum msgdir subj
  872. IF bbsWrite.rexx(comm) THEN
  873.   DO
  874.     IF EXISTS(orig) THEN
  875.       DO
  876.         IF readlines(orig 1) THEN BREAK
  877.         xmsg=countcheck(bbspath'Numbers/LastMessage'msgdir mes)
  878.         IF WORDS(lynes.1)>3 THEN lynes.1=lynes.1 xmsg
  879.         ELSE lynes.1=lynes.1'   Reply' xmsg
  880.         CALL DELAY(28)    /* allow 1/2 sec for read to close */
  881.         CALL savelines(orig)
  882.       END
  883.   END
  884. RETURN
  885.  
  886.  
  887. msgmark:
  888. PARSE ARG markname markdir markmsg .
  889. IF OPEN(f,bbspath'Users/'markname,'R')=0 THEN RETURN
  890. mlines.=''
  891. DO mi=1
  892.   temp=READLN(f)
  893.   IF EOF(f) THEN LEAVE mi
  894.   mlines.mi=STRIP(temp)
  895. END
  896. CALL CLOSE(f)
  897. mlines.0=mi-1
  898. CALL DELAY(28)
  899. mlines.24=STRIP(mlines.24 markdir'/'markmsg)
  900. IF OPEN(f,bbspath'Users/'markname,'W')=0 THEN RETURN
  901. DO mi=1 TO mlines.0
  902.   CALL WRITELN(f,mlines.mi)
  903. END
  904. CALL CLOSE(f)
  905. RETURN
  906.  
  907.  
  908. checktime:
  909. IF ~frombb THEN RETURN
  910. IF TIME('E')>maxtime THEN EXIT
  911. IF TIME('E')>(maxtime-120) THEN SAY '*** Less than 2 minutes left! ***'CR
  912. MSG RIGHT(' ',66-LENGTH(name)) '1B'x'M'||''||''||' 'name' level 'level' '||''
  913. CALL checkdcd()
  914. RETURN
  915.  
  916.  
  917. waiting:
  918. CALL checktime()
  919. IF waitchar='Q' THEN
  920.   DO
  921.     waitchar=''
  922.     RETURN
  923.   END
  924. waitchar=''
  925. IF nonstop=1 THEN RETURN
  926. OPTIONS PROMPT pen3'                          RETURN=Continue 'def
  927. PULL waitchar
  928. CALL cleanline(1)
  929. CALL checkdcd()
  930. RETURN
  931.  
  932.  
  933. waiting2:
  934. CALL checktime()
  935. IF nonstop=1 THEN RETURN 0
  936. waitchar=getinput(1 1 pen3'   Q=Quit   N=Non-Stop   RETURN=Continue  'def)
  937. IF waitchar='N' THEN
  938.   DO
  939.     nonstop=1
  940.     SAY lineup||pen3'To EXIT non-stop scrolling of text, press CTRL-E        'def||CR
  941.     SAY CR
  942.     CALL DELAY(99)
  943.     waitchar=''
  944.   END
  945. CALL cleanline(1)
  946. CALL checkdcd()
  947. IF waitchar='Q' THEN RETURN 1
  948. RETURN 0
  949.  
  950.  
  951. killmark:
  952. PARSE ARG kdir kmsg .
  953. IF data.24='' THEN RETURN
  954. markword=FIND(data.24,kdir'/'kmsg)
  955. IF markword>0 THEN data.24=STRIP(DELWORD(data.24,markword,1))
  956. RETURN
  957.  
  958.  
  959. readmarked:
  960. mrknum=WORDS(data.24)
  961. IF mrknum=0 THEN RETURN
  962. SAY 'Reading only messages addressed to you...'CR
  963. mrklist=data.24
  964. msgcom=''
  965. DO rmki=1 TO mrknum WHILE msgcom~='Q'
  966.   tempk=WORD(mrklist,rmki)
  967.   PARSE VAR tempk mkdir'/'mkmsg .
  968.   IF ~EXISTS(msgpath||tempk) THEN
  969.     DO
  970.       CALL killmark(mkdir mkmsg)
  971.       SAY CR
  972.       SAY 'Message number' mkmsg 'in the' msg.mkdir 'conference is missing!'CR
  973.       SAY CR
  974.       ITERATE rmki
  975.     END
  976.   msgdir=mkdir
  977.   savelast=lastread.msgdir
  978.   CALL readmsg(1 mkmsg)
  979.   IF mkmsg>savelast THEN lastread.msgdir=mkmsg
  980.   ELSE lastread.msgdir=savelast
  981. END
  982. CALL savedata(1)
  983. RETURN
  984.  
  985.  
  986. msgcount:
  987. ARG countdir .
  988. lastmess=0
  989. totmsgs=0
  990. unred=0
  991. IF ~EXISTS(msgpath||countdir) THEN RETURN
  992. IF STATEF(msgpath||countdir)=msg.countdir.1 THEN totmsgs=msg.countdir.0
  993. ELSE
  994.   DO
  995.     totmsgs=WORDS(SHOWDIR(msgpath||countdir))
  996.     msg.countdir.0=totmsgs
  997.     msg.countdir.1=STATEF(msgpath||countdir)
  998.   END
  999. IF countdir>level | FIND(data.21,i)>0 THEN RETURN
  1000. lastread.countdir=WORD(data.22,countdir)
  1001. IF ~DATATYPE(lastread.countdir,'W') THEN lastread.countdir=0
  1002. lastmess=countcheck(bbspath'Numbers/LastMessage'countdir 0)
  1003. IF lastread.countdir<0 THEN RETURN
  1004. firstmess=countcheck(bbspath'Numbers/FirstMessage'countdir 0)
  1005. IF lastread.countdir<firstmess THEN lastread.countdir=firstmess-1
  1006. IF lastmess>0 THEN
  1007.   IF lastread.countdir>=0 THEN
  1008.     DO
  1009.       IF lastread.countdir<(firstmess-1) THEN lastread.countdir=firstmess-1
  1010.       unred=lastmess-lastread.countdir
  1011.       IF unred>totmsgs THEN unred=totmsgs
  1012.       cline=RIGHT(unred,5) 'new of' RIGHT(lastmess,5) 'messages,'
  1013.       cline=cline RIGHT(totmsgs,5) 'still online in' 
  1014.       cline=cline RIGHT(countdir,2)',' msg.countdir
  1015.       SAY pen6||cline||def||CR
  1016.     END
  1017. RETURN
  1018.  
  1019.  
  1020. searchmsgdir:
  1021. msglist=SHOWDIR(msgpath||msgdir)
  1022. IF WORDS(msglist)>0 THEN SAY lineup||RIGHT(msg.msgdir,40)||CR
  1023. qi=WORDS(msglist)
  1024. DO wi=1 TO qi
  1025.   CALL busywait(8 wi qi)
  1026.   messnum=WORD(msglist,wi)%1
  1027.   IF textsearch(msgpath||msgdir'/'messnum searcharg) THEN
  1028.     DO
  1029.       CALL busywait(4 0)
  1030.       savelast=lastread.msgdir
  1031.       CALL readmsg(0 messnum)
  1032.       lastread.msgdir=savelast
  1033.       IF msgcom='Q' THEN RETURN
  1034.       CALL busywait(4 1)
  1035.     END
  1036. END
  1037. CALL busywait(4 0)
  1038. RETURN
  1039.  
  1040.  
  1041. busywait:
  1042. ARG bii bi bt 
  1043. IF bii>4 & bi//(10*bii)=0 THEN CALL checkdcd()
  1044. IF bbsprefs.21=0 THEN RETURN
  1045. IF bi<1 THEN
  1046.   DO
  1047.     CALL WRITECH(STDOUT,'080808'x)
  1048.     IF ni<1 & i>999998 & wi>999998 THEN SAY CR
  1049.     RETURN
  1050.   END
  1051. IF bi=1 THEN CALL WRITECH(STDOUT,'   ')
  1052. IF bi//(bii%2)~=0 THEN RETURN
  1053. b=bi//bii
  1054. IF b=0 | b=bii%2 THEN
  1055.   DO
  1056.     tp=RIGHT((bi*100)%bt,2)'%'
  1057.     CALL WRITECH(STDOUT,'080808'x||tp)
  1058.   END
  1059. RETURN
  1060.  
  1061.  
  1062. cleanline:
  1063. ARG lflag .
  1064. IF nonstop=0 & clr~='' & frombb THEN
  1065.   DO
  1066.     Send clr
  1067.     RETURN
  1068.   END
  1069. cline=lineup||LEFT(' ',78)
  1070. IF lflag=1 THEN cline=cline||lineup
  1071. SAY cline||CR
  1072. RETURN
  1073.  
  1074.  
  1075. countcheck:
  1076. PARSE ARG fname' 'cknum' '.
  1077. IF ~EXISTS(fname) THEN
  1078.   DO
  1079.     IF cknum=0 THEN RETURN 0
  1080.     IF OPEN(f,fname,'W')=0 THEN RETURN 0
  1081.     CALL WRITELN(f,cknum)
  1082.     CALL CLOSE(f)
  1083.     RETURN cknum
  1084.   END
  1085. IF OPEN(f,fname,'R')=0 THEN
  1086.   DO
  1087.     CALL DELAY(99)
  1088.     IF OPEN(f,fname,'R')=0 THEN RETURN cknum
  1089.   END
  1090. retval=STRIP(READLN(f))
  1091. CALL CLOSE(f)
  1092. IF ~DATATYPE(retval,'W') THEN retval=0
  1093. IF ~DATATYPE(cknum,'W') THEN cknum=0
  1094. IF retval<cknum THEN
  1095.   DO
  1096.     IF OPEN(f,fname,'W')~=0 THEN
  1097.       DO
  1098.         CALL WRITELN(f,cknum)
  1099.         CALL CLOSE(f)
  1100.         RETURN cknum
  1101.       END
  1102.   END
  1103. RETURN retval
  1104.  
  1105.  
  1106. getinput:
  1107. PARSE ARG upflag' 'oneflag' 'pline
  1108. CALL checktime()
  1109. OPTIONS PROMPT pline
  1110. PARSE PULL inarg
  1111. inarg=STRIP(inarg)
  1112. IF upflag THEN inarg=UPPER(inarg)
  1113. IF oneflag THEN inarg=LEFT(inarg,1)
  1114. inarg=cleanstring(0':'inarg)
  1115. RETURN inarg
  1116.  
  1117.  
  1118. checkdcd:
  1119. IF ~frombb THEN RETURN
  1120. dcd
  1121. IF RC=0 THEN
  1122.   DO
  1123.     DO dcds=1 TO 3  /* 5 second delay */
  1124.       CALL DELAY(50)
  1125.       dcd
  1126.       IF RC~=0 THEN RETURN
  1127.     END
  1128.     dcd
  1129.     IF RC=0 THEN EXIT
  1130.   END
  1131. xmsg=GETCLIP('BBS_MESSAGE')
  1132. IF xmsg~='' THEN
  1133.   DO
  1134.     CALL SETCLIP('BBS_MESSAGE')
  1135.     SAY CR
  1136.     SAY bak2' Message From BBBBS: 'def||CR
  1137.     SAY xmsg||CR
  1138.     SAY CR
  1139.     CALL waiting()
  1140.   END
  1141. IF POS('G',GETCLIP('BBS_COMMAND'))>0 THEN EXIT
  1142. RETURN
  1143.  
  1144.  
  1145. cleanstring:
  1146. PARSE ARG nflag':'cstr
  1147. IF nflag=1 THEN
  1148.   DO
  1149.     cstr=COMPRESS(cstr,"'`")
  1150.     cstr=TRANSLATE(cstr,,namemask)
  1151.     cstr=SPACE(cstr,1,'_')
  1152.     RETURN cstr
  1153.   END
  1154. bot=XRANGE(,'1F'x)
  1155. IF nflag=2 THEN bot=COMPRESS(bot,'1B'x)  /* ESC for ANSI */
  1156. ELSE cstr=strip_ansi(cstr)
  1157. top=XRANGE('7F'x)
  1158. cstr=COMPRESS(cstr,bot||top)
  1159. IF nflag=0 THEN cstr=STRIP(cstr)
  1160. RETURN cstr
  1161.  
  1162.  
  1163. do_eleven:
  1164. ARG am tc at .
  1165. data.11=am 'minutes per call,' tc 'calls per day,'
  1166. data.11=data.11 at 'more calls today'
  1167. RETURN
  1168.  
  1169.  
  1170. savedata:
  1171. ARG messflag .
  1172. IF data.5='' THEN RETURN
  1173. SAY 'Updating...             'lineup||CR
  1174. temp=GETCLIP(name'_UPDATE')
  1175. IF temp~='' THEN
  1176.   DO
  1177.     CALL SETCLIP(name'_UPDATE')
  1178.     PARSE VAR temp upfiles' 'upbytes' 'upmail' 'upmsg
  1179.     IF upfiles>0 THEN
  1180.       DO
  1181.         files=WORD(data.14,1)
  1182.         bytes=WORD(data.14,3)
  1183.         IF DATATYPE(files,'W') THEN upfiles=upfiles+files
  1184.         IF DATATYPE(bytes,'W') THEN bytes=upbytes
  1185.         data.14=upfiles 'files' bytes 'bytes.' DATE()
  1186.       END
  1187.     IF upmail>0 THEN
  1188.       DO
  1189.         mail=WORD(data.17,2)
  1190.         IF DATATYPE(mail,'W') THEN upmail=upmail+mail
  1191.         data.17=WORD(data.17,1) upmail WORD(data.17,3)
  1192.       END
  1193.     IF upmsg~='' THEN
  1194.       DO
  1195.         temp=data.23
  1196.         DO i=1 TO level
  1197.           smsg=WORD(temp,i)
  1198.           IF ~DATATYPE(smsg,'W') THEN smsg=0
  1199.           IF FIND(upmsg,i) THEN smsg=smsg+1
  1200.           data.23=data.23 smsg
  1201.         END
  1202.       END
  1203.   END
  1204. SIGNAL OFF BREAK_E
  1205. IF frombb THEN
  1206.   DO
  1207.     Status Trans
  1208.     data.6=STRIP(RESULT)
  1209.   END
  1210. IF lastbrowse>0 THEN
  1211.   DO
  1212.     IF WORDS(data.16)>1 THEN data.16=DELWORD(data.16,1,1)
  1213.     ELSE data.16=DATE('S') TIME()
  1214.     data.16=lastbrowse data.16
  1215.   END
  1216. IF messflag THEN
  1217.   DO
  1218.     userexclude.=0
  1219.     DO si=1 TO WORDS(data.22)
  1220.       IF WORD(data.22,si)=-1 THEN userexclude.si=1
  1221.     END
  1222.     data.22=''
  1223.     data.23=''
  1224.     DO si=1 TO level
  1225.       IF ~DATATYPE(lastread.si,'W') THEN lastread.si=0
  1226.       IF userexclude.si THEN data.22=data.22 '-1'
  1227.       ELSE data.22=data.22 lastread.si
  1228.       IF ~DATATYPE(totwrit.si,'W') THEN totwrit.si=0
  1229.       data.23=data.23 totwrit.si
  1230.     END
  1231.   END
  1232. IF clear_marked=1 THEN data.24=''
  1233. clear_marked=0
  1234. IF writeopen(bbspath'USERS/'name)=0 THEN RETURN
  1235. IF data.0<27 THEN data.0=27
  1236. DO i=1 TO data.0
  1237.   CALL WRITELN(f,data.i)
  1238. END
  1239. CALL CLOSE(f)
  1240. SAY 'User' name 'has been updated.'CR
  1241. RETURN
  1242.  
  1243.  
  1244. loaddata:
  1245. IF name='' THEN RETURN 0
  1246. IF ~readopen(bbspath'USERS/'name) THEN RETURN 0
  1247. data.=''
  1248. DO i=1
  1249.   line=READLN(f)
  1250.   IF EOF(f) THEN BREAK
  1251.   data.i=line
  1252. END
  1253. data.0=i-1
  1254. CALL CLOSE(f)
  1255. city=docity(data.3)
  1256. winnings=WORD(data.18,1)
  1257. IF ~DATATYPE(winnings,'N') THEN winnings=0
  1258. IF WORDS(data.16)<3 THEN data.16='0 19900101 00:00:00'
  1259. lastbrowse=WORD(data.16,1)
  1260. IF ~DATATYPE(lastbrowse,'W') THEN lastbrowse=0
  1261. level=data.20
  1262. DO i=1 TO level
  1263.   lastread.i=WORD(data.22,i)
  1264.   IF ~DATATYPE(lastread.i,'W') THEN lastread.i=0
  1265.   totwrit.i=WORD(data.23,i)
  1266.   IF ~DATATYPE(totwrit.i,'W') THEN totwrit.i=0
  1267. END
  1268. password=data.5
  1269. IF frombb THEN
  1270.   DO
  1271.     IF data.6='' THEN
  1272.       DO
  1273.         Status Trans
  1274.         data.6=RESULT
  1275.       END
  1276.     ELSE
  1277.       DO
  1278.         IF RIGHT(UPPER(data.6),2)='-G' THEN data.6='G'
  1279.         IF RIGHT(UPPER(data.6),3)='-1K' THEN data.6='K'
  1280.         IF LEFT(UPPER(data.6),1)='A' THEN data.6='Z'
  1281.         IF frombb THEN Set UPPER(LEFT(data.6,1))
  1282.       END
  1283.   END
  1284. IF ~DATATYPE(data.7,'W') THEN data.7=20
  1285. IF data.7<5 THEN data.7=5
  1286. linesperpage=data.7
  1287. IF ~frombb THEN linesperpage=20
  1288. IF FIND(UPPER(data.8),'TERSE')>0 THEN terseflag=1
  1289. ELSE terseflag=0
  1290. IF FIND(UPPER(data.8),'COLOR')>0 THEN colorflag=1
  1291. ELSE colorflag=0
  1292. CALL colors(colorflag)
  1293. clr=''
  1294. IF frombb & FIND(UPPER(data.8),'CLEAR')>0 THEN clr='0C'x
  1295. menu='ALL'
  1296. IF FIND(UPPER(data.8),'MENUS')>0 THEN
  1297.   DO
  1298.     menuflag=1
  1299.     menu='MAIN'
  1300.   END
  1301. ELSE IF FIND(UPPER(data.8),'MENU')>0 THEN menuflag=1
  1302. ELSE menuflag=0
  1303. IF level=0 THEN menu='NEW'
  1304. IF DATATYPE(WORD(data.11,3),'W') THEN
  1305.   DO
  1306.     PARSE VAR data.11 amins . atimes .
  1307.     CALL do_eleven(amins bbsprefs.16 atimes)
  1308.   END
  1309. data.21=UPPER(data.21)
  1310. RETURN 1
  1311.  
  1312.  
  1313. savelines:
  1314. PARSE ARG tempname .
  1315. IF OPEN(f,tempname,'W')=0 THEN
  1316.   DO
  1317.     line='***' tempname 'failed to open for saving!'
  1318.     CALL send2log(line)
  1319.     SAY line||CR
  1320.     RETURN 1
  1321.   END
  1322. DO wi=1 TO lynes.0
  1323.   CALL WRITELN(f,lynes.wi)
  1324. END
  1325. CALL CLOSE(f)
  1326. RETURN 0
  1327.  
  1328.  
  1329. seelines:
  1330. ARG fancy .
  1331. DO i=1 TO lynes.0
  1332.   IF fancy=0 THEN SAY lynes.i||def||CR
  1333.   ELSE
  1334.     DO
  1335.       IF LEFT(lynes.i,2)=': ' & WORDS(lynes.i)=2 THEN ITERATE i
  1336.       ELSE IF LEFT(lynes.i,10)='Directory ' | LEFT(lynes.i,5)='=====' THEN
  1337.         SAY pen3||lynes.i||def||CR
  1338.       ELSE SAY lynes.i||CR
  1339.       IF fancy=2 & colorflag=1 THEN
  1340.         DO
  1341.           IF searcharg~='' THEN
  1342.             DO
  1343.               testpos=POS(UPPER(searcharg),UPPER(lynes.i))
  1344.               IF testpos>0 THEN
  1345.                 SAY LEFT(' ',testpos-1)||pen3||lineup||UPPER(searcharg)||def||CR
  1346.             END
  1347.           IF i=1 THEN
  1348.             IF WORD(lynes.1,3)='Reply' THEN
  1349.               DO
  1350.                 testpos=WORDINDEX(lynes.1,3)
  1351.                 SAY LEFT(' ',testpos-1)||pen3||lineup||SUBSTR(lynes.1,testpos)||def||CR
  1352.               END
  1353.         END
  1354.     END
  1355.   IF i//linesperpage=0 & i<lynes.0 THEN
  1356.     IF waiting2() THEN LEAVE i
  1357. END
  1358. nonstop=0
  1359. RETURN
  1360.  
  1361.  
  1362. writeopen:
  1363. PARSE ARG fname
  1364. CALL CLOSE(f)
  1365. ok=OPEN(f,fname,'W')
  1366. IF ok~=0 THEN RETURN 1
  1367. line=fname 'failed to open for writing!'
  1368. SAY line||CR
  1369. CALL send2log(line)
  1370. RETURN 0
  1371.  
  1372.  
  1373. readopen:
  1374. PARSE ARG fname
  1375. ok=OPEN(f,fname,'R')
  1376. IF ok~=0 THEN RETURN 1
  1377. line=fname 'failed to open for reading!'
  1378. SAY line||CR
  1379. CALL send2log(line)
  1380. RETURN 0
  1381.  
  1382.  
  1383. readlines:
  1384. CALL CLOSE(f)
  1385. PARSE ARG tempname readstart .
  1386. IF ~readopen(tempname) THEN RETURN 1
  1387. IF readstart<2 THEN lynes.=''
  1388. DO ri=readstart
  1389.   line=READLN(f)
  1390.   IF EOF(f) THEN BREAK
  1391.   lynes.ri=line
  1392. END
  1393. lynes.0=ri-1
  1394. CALL CLOSE(f)
  1395. DO ri=lynes.0 TO 0 BY -1 WHILE LENGTH(lynes.ri)=0 | LEFT(UPPER(lynes.ri),2)='/E' | LEFT(UPPER(lynes.ri),2)='/S'
  1396. END
  1397. lynes.0=ri
  1398. RETURN 0
  1399.  
  1400.  
  1401. strip_ansi:
  1402. PARSE ARG aline 
  1403. n=POS('1B'x,aline)
  1404. DO WHILE n>0
  1405.   DO k=2
  1406.     IF DATATYPE(SUBSTR(aline,n+k,1),'M') | (n+k+1)>LENGTH(aline) THEN
  1407.       leave k
  1408.   END
  1409.   aline=DELSTR(aline,n,k+1)
  1410.   n=POS('1B'x,aline)
  1411. END
  1412. RETURN aline
  1413.  
  1414.  
  1415. send2log:
  1416. PARSE ARG sendline
  1417. IF ~frombb THEN RETURN
  1418. logfile=bbspath'Logs/log.'DATE('S')    /* daily logs */
  1419. fl='W'
  1420. IF EXISTS(logfile) THEN fl='A'
  1421. IF ~OPEN('log',logfile,fl) THEN
  1422.   DO
  1423.     IF ~OPEN('log',logfile,fl) THEN
  1424.       DO
  1425.         SAY 'failed to open log file'
  1426.         RETURN
  1427.      END
  1428.   END
  1429. CALL WRITELN('log','bbsMsg:' sendline)
  1430. CALL CLOSE('log')
  1431. RETURN
  1432.  
  1433.  
  1434. colors:
  1435. ARG onoff
  1436. IF onoff THEN
  1437.   DO;def='';pen2='';pen3='';pen6='';bak2='';END
  1438. ELSE
  1439.   DO;def='';pen2='';pen3='';pen6='';bak2='';END
  1440. lineup='1B'x'M'
  1441. RETURN
  1442.  
  1443.  
  1444. BREAK_E:
  1445. i=999999
  1446. ri=999999
  1447. wi=999999
  1448. newi=999999
  1449. RETURN
  1450.  
  1451.  
  1452. BREAK_C:
  1453. EXIT
  1454.  
  1455.  
  1456. FAILURE:
  1457. SYNTAX:
  1458. lin.1=''ERRORTEXT(RC)''
  1459. lin.2=SIGL-1     SOURCELINE(SIGL-1)
  1460. lin.3=SIGL ''SOURCELINE(SIGL)''
  1461. lin.4=SIGL+1     SOURCELINE(SIGL+1)
  1462. DO er=1 TO 4
  1463.   IF level>sysoplevel | ~frombb THEN SAY 'bbsMsg:' lin.er||CR
  1464.   IF frombb THEN CALL send2log(lin.er)
  1465. END
  1466. EXIT
  1467.  
  1468. /* bbsMsg.rexx */
  1469.